const WebScoket = require('ws')
const jwt = require('jsonwebtoken')

const token = jwt.sign({
  data: 'footbar'
},'secret',{
  expiresIn: '15d'
})
console.log(token)


const wss = new WebScoket.Server({
  port: 8000
})

const grop = {

}
const timeInterval = 5000


wss.on('connection', (ws) => {
  ws.isLive = true
  console.log('---------------------')
  console.log('someUser is connect')
  console.log('---------------------')
  ws.on('message', msg => {
    
    msg = JSON.parse(msg)
    if(msg.event === 'auth') {
      jwt.verify(token, 'secret', (err, decode) => {
        if(err) {
          console.log('author err')
          return
        }else {
          ws.isAuth = true
        }
        console.log(JSON.stringify(decode))
      })

    }
    if(!ws.isAuth) {
      ws.send(JSON.stringify({
        event: 'noAuth',
        message: 'please auth agin, your token is invaild'
      }))
      return
    }

    if(msg.event === 'heartbeat' && msg.message === 'pong') {
      console.log('++++++++++++++++++++++')
      console.log('beat')
      console.log('++++++++++++++++++++++')
      ws.isLive = true
      return
    }
    if(msg.name) {
      ws.name = msg.name
    }
    if(msg.roomId && typeof ws.roomId === 'undefined') {
      ws.roomId = msg.roomId
      if(typeof grop[ws.roomId] === 'undefined') {
        grop[ws.roomId] = 1
      }else {
        grop[ws.roomId]++
      }
    }
    msg.nums = grop[ws.roomId]
    wss.clients.forEach(function each(client) {
      if(client!== ws && client.readyState === WebScoket.OPEN && client.roomId === ws.roomId) {
        client.send(JSON.stringify(msg))
      }
    })
  })
  ws.on('close', function() {
    console.log('one client is close :'+ ws.name)
    wss.clients.forEach(function each(client) {
      if(client!== ws && client.readyState === WebScoket.OPEN && client.roomId === ws.roomId) {
        client.send(JSON.stringify({
          name: ws.name,
          event: 'logout'
        }))
      }
    })
  })
})


const interval = setInterval(() => {
  wss.clients.forEach(ws => {
    if(ws.isLive === false) {
      return ws.terminate()
    }
    ws.isLive = false
    ws.send(JSON.stringify({
      event: 'heartbeat',
      message: 'ping'
    }))
  })
}, timeInterval)